package com.example.util;

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;

import java.text.SimpleDateFormat;
import java.time.Instant;
import java.time.OffsetDateTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Calendar;
import java.util.Date;

import static cn.hutool.core.date.DateUtil.formatDate;
import static cn.hutool.core.date.DateUtil.parse;

@Slf4j
public class DateUtil {

    public static final String FORMAT = "yyyy-MM-dd'T'HH:mm:ss.SSSZ";
    public static final String YYYY_MM_DD_HH_MM_SS = "yyyy-MM-dd HH:mm:ss";

    public static final String YYYY_MM_DD = "yyyy-MM-dd";

    public static final String YYYY_MM_DD_T_HH_MM_SS = "yyyy-MM-dd'T'HH:mm:ss";

    public static Date stringToDate(String str, String format) {
        if (StringUtils.isBlank(str) || StringUtils.isBlank(format)) {
            return null;
        }
        Date date = null;
        try {
            SimpleDateFormat sdf = new SimpleDateFormat(format);
            date = sdf.parse(str);
        } catch (Exception exception) {
            log.error("stringToDate:{}", str, exception);
        }
        return date;
    }

    /**
     * iso时间转date减8
     *
     * @param str 时间
     * @return date
     */
    public static Date stringToDateOfIsoOffsetHour8(String str) {
        if (StringUtils.isBlank(str)) {
            return null;
        }
        Date date = null;
        try {
            OffsetDateTime parse = OffsetDateTime.parse(str);
            Instant instant = parse.toInstant();
            date = Date.from(instant);
            date = cn.hutool.core.date.DateUtil.offsetHour(date, -8);
        } catch (Exception exception) {
            log.error("stringToDateOfIso:{}", str, exception);
        }
        return date;
    }

    /**
     * iso时间转date
     *
     * @param str 时间
     * @return date
     */
    public static Date stringToDateOfIso(String str) {
        if (StringUtils.isBlank(str)) {
            return null;
        }
        Date date = null;
        try {
            OffsetDateTime parse = OffsetDateTime.parse(str);
            Instant instant = parse.toInstant();
            date = Date.from(instant);
        } catch (Exception exception) {
            log.error("stringToDateOfIso:{}", str, exception);
        }
        return date;
    }

    /**
     * 时间增加天数
     *
     * @param date 日期
     * @return num 增加天数
     */
    public static Date dateAddDate(Date date, int num) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.DAY_OF_MONTH, num);
        return calendar.getTime();
    }

    public static int getYearFoDate(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        return calendar.get(Calendar.YEAR);
    }

    public static String getNowDateStr(Date date, String format) {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat(format);
        return simpleDateFormat.format(date);
    }

    /**
     * 忽略两个日期的时分秒，计算相差天数
     */
    public static long differenceDays(Date date1, Date date2) {
        Calendar cal1 = Calendar.getInstance();
        cal1.setTime(date1);
        cal1.set(Calendar.HOUR_OF_DAY, 0);
        cal1.set(Calendar.MINUTE, 0);
        cal1.set(Calendar.SECOND, 0);
        cal1.set(Calendar.MILLISECOND, 0);

        Calendar cal2 = Calendar.getInstance();
        cal2.setTime(date2);
        cal2.set(Calendar.HOUR_OF_DAY, 0);
        cal2.set(Calendar.MINUTE, 0);
        cal2.set(Calendar.SECOND, 0);
        cal2.set(Calendar.MILLISECOND, 0);
        long diffInMillis = Math.abs(cal2.getTimeInMillis() - cal1.getTimeInMillis());
        return diffInMillis / (1000 * 60 * 60 * 24);
    }

    /**
     * 转为23点59分59秒
     *
     * @param
     * @return
     */
    public static Date endOfDate(Date date) {
        String dateStr = formatDate(date) + " 23:59:59";
        return parse(dateStr, "yyyy-MM-dd HH:mm:ss");
    }

    /**
     * 时间戳转日期
     * @param timestamp
     * @param format
     * @return
     */
    public static String localDateTimeFormat(Long timestamp, String format){
        ZonedDateTime zonedDateTime = Instant.ofEpochMilli(timestamp)
                .atZone(ZoneId.systemDefault()); // 或指定时区 ZoneId.of("Asia/Shanghai")

        DateTimeFormatter formatter = DateTimeFormatter.ofPattern(format);
        return zonedDateTime.format(formatter);
    }

}
